import { Control, ControlProps } from "../common";
import { ShoppingService } from "../../user/services/shoppingService"
import { PageSpiner, PageSpinerContext } from "../../share/controls/page-spiner";
import React = require("react");
import { ImageService } from "maishu-services-sdk";
import { renderImage } from "maishu-ui-toolkit";
import { ShoppingCartService } from "user/services/shoppingCartService";

interface Props extends ControlProps<SingleColunmProducts> {

}

export interface State {

    /** 商品来源 */
    productSourceType: 'category' | 'custom',

    /** 图片大小 */
    imageSize: 'small' | 'medium' | 'large',

    /** 商品名称行数 */
    productNameLines: 'singleLine' | 'doubleColumn',

    /** 商品数量 */
    productsCount: number,

    /** 商品类别 */
    categoryId?: string,

    /** 选取要展示的商品编号 */
    productIds?: string[],

    /** 价格右侧 */
    buyButton?: 'priceRight'

    products: Product[]


}

type LoadResult = ReturnType<SingleColunmProducts["loadData"]> extends Promise<infer T> ? T : any;
export default class SingleColunmProducts extends Control<Props, State> {
    key: string;
    shoppingCartService: ShoppingCartService;

    get persistentMembers(): (keyof State)[] {
        return [
            "productSourceType", "imageSize", "productNameLines",
            "productsCount", "categoryId", "productIds"
        ];
    }

    private shopService: ShoppingService;
    private imageService: ImageService;

    constructor(props) {
        super(props)

        this.hasCSS = true;
        let page = this.props.mobilePage.props.elementPage;
        this.shopService = page.createService(ShoppingService);
        this.imageService = page.createService(ImageService);
        this.shoppingCartService = page.createService(ShoppingCartService);

        this.state = {
            productSourceType: "category", imageSize: "small",
            productNameLines: "singleLine", productsCount: 1,
            products: [],
        }

        this.shoppingCartService.onChanged(this, (items) => {
            let { products } = this.state;
        })
    }

    imageUrl(imageId: string) {
        if (!imageId)
            return;

        if (imageId.startsWith("http://"))
            return imageId;

        return this.imageService.imageSource(imageId, 120, 120)
    }

    async loadData() {
        let { categoryId, productsCount, productIds } = this.state;
        let sourceType = this.state.productSourceType;
        let products: Product[]
        if (sourceType == 'category') {
            products = await this.shopService.productsByCategory(productsCount, categoryId)
        }
        else if (sourceType == 'custom') {
            products = productIds ? await this.shopService.productsByIds(productIds) : []
        }
        else {
            products = await this.shopService.products(0);
        }

        let shoppingCartItems = await this.shoppingCartService.items();

        return { products, shoppingCartItems }
    }

    _render(h: any): JSX.Element | JSX.Element[] {

        let { imageSize, productNameLines } = this.state
        let titleClassName = productNameLines == 'singleLine' ? 'name single-line' : 'name double-line';
        let leftClassName: string, rightClassName: string;
        switch (imageSize) {
            case 'small':
            default:
                leftClassName = 'col-xs-3';
                rightClassName = 'col-xs-9';
                break;
            case 'medium':
                leftClassName = 'col-xs-4';
                rightClassName = 'col-xs-8';
                break;
            case 'large':
                leftClassName = 'col-xs-5';
                rightClassName = 'col-xs-7';
                break;
        }

        return <PageSpiner load={() => this.loadData()} showSpiner={this.isRuntime}>
            <PageSpinerContext.Consumer>
                {args => {
                    let result = (args.result || { products: [], shoppingCartItems: [] }) as LoadResult;
                    let { products, shoppingCartItems } = result;
                    return products.map(p => {
                        let item = shoppingCartItems.filter(o => o.ProductId == p.Id)[0];
                        return <React.Fragment key={p.Id}>
                            <div key={p.Id} className="product single">
                                <div className={leftClassName}>
                                    <img key={p.Id} className="product-image" src={this.imageUrl(p.ImagePath)} data-url={p.ImagePath}
                                        ref={e => e ? renderImage(e, { imageSize: { width: 120, height: 120 } }) : null} />
                                </div>
                                <div className={rightClassName}>
                                    <div className={`${titleClassName} btn-link`} product-id={p.Id}>{p.Name}</div>
                                    <div className="price-bar">
                                        <span className="pull-left price-color">￥{p.Price}</span>
                                        <div className="pull-right">
                                            <BuyButton shoppingCartService={this.shoppingCartService} product={p}
                                                count={item ? item.Count : 0} />
                                        </div>
                                    </div>

                                </div>
                                <div className="clearfix"></div>
                            </div>
                            <hr />
                        </React.Fragment>
                    })
                }}
            </PageSpinerContext.Consumer>
        </PageSpiner>
    }

}

class BuyButton extends React.Component<{ shoppingCartService: ShoppingCartService, product: Product, count: number }, { count: number }> {
    constructor(props) {
        super(props);
        this.state = { count: this.props.count };
        this.props.shoppingCartService.onChanged(this, (items) => {
            let shoppingCartItem = items.filter(o => o.ProductId == this.props.product.Id)[0];
            if (shoppingCartItem) {
                this.setState({ count: shoppingCartItem.Count });
            }
            else {
                this.setState({ count: 0 })
            }
        })
    }

    decreaseProductCount() {
        let { count } = this.state;
        if (count <= 0)
            return;

        count = count - 1;
        this.setState({ count });
        return this.props.shoppingCartService.setItemCount(this.props.product, count);
    }

    increaseProductCount() {
        let { count } = this.state;
        count = count + 1;
        this.setState({ count });
        return this.props.shoppingCartService.setItemCount(this.props.product, count);
    }
    render() {
        let { count } = this.state;
        return <div className="buy-button input-group pull-right">
            <span className="input-group-addon" onClick={() => this.decreaseProductCount()}>
                <i className="icon-minus" />
            </span>
            <input type="number" min={1} className="form-control" value={count}
                style={{ padding: 0, textAlign: "center" }}
                onChange={e => {
                    let count = Number.parseInt(e.target.value);
                    if (!isNaN(count) && count > 0) {
                        this.setState({ count });
                    }
                }} />
            <span className="input-group-addon" onClick={() => this.increaseProductCount()}>
                <i className="icon-plus" />
            </span>
        </div>
    }
}